import { BaseScraper, type ScrapingResult } from './BaseScraper.js';
import { DataConverter, type ComponentData } from './DataConverter.js';
import type { CheerioAPI } from 'cheerio';

/**
 * Ant Design 官方组件数据收集器
 */
export class AntDesignScraper extends BaseScraper {
  private readonly componentsApiUrl = 'https://ant.design/components/';
  private readonly apiDocsUrl = 'https://ant.design/components/';
  
  // 组件分类映射
  private readonly categoryMap = new Map([
    // 通用
    ['Button', '通用'],
    ['FloatButton', '通用'],
    ['Icon', '通用'],
    ['Typography', '通用'],
    
    // 布局
    ['Divider', '布局'],
    ['Grid', '布局'],
    ['Layout', '布局'],
    ['Space', '布局'],
    ['Splitter', '布局'],
    
    // 导航
    ['Affix', '导航'],
    ['Breadcrumb', '导航'],
    ['Dropdown', '导航'],
    ['Menu', '导航'],
    ['Pagination', '导航'],
    ['Steps', '导航'],
    
    // 数据录入
    ['AutoComplete', '数据录入'],
    ['Cascader', '数据录入'],
    ['Checkbox', '数据录入'],
    ['ColorPicker', '数据录入'],
    ['DatePicker', '数据录入'],
    ['Form', '数据录入'],
    ['Input', '数据录入'],
    ['InputNumber', '数据录入'],
    ['Mentions', '数据录入'],
    ['Radio', '数据录入'],
    ['Rate', '数据录入'],
    ['Select', '数据录入'],
    ['Slider', '数据录入'],
    ['Switch', '数据录入'],
    ['TimePicker', '数据录入'],
    ['Transfer', '数据录入'],
    ['TreeSelect', '数据录入'],
    ['Upload', '数据录入'],
    
    // 数据展示
    ['Avatar', '数据展示'],
    ['Badge', '数据展示'],
    ['Calendar', '数据展示'],
    ['Card', '数据展示'],
    ['Carousel', '数据展示'],
    ['Collapse', '数据展示'],
    ['Descriptions', '数据展示'],
    ['Empty', '数据展示'],
    ['Flex', '数据展示'],
    ['Image', '数据展示'],
    ['List', '数据展示'],
    ['Popover', '数据展示'],
    ['QRCode', '数据展示'],
    ['Segmented', '数据展示'],
    ['Statistic', '数据展示'],
    ['Table', '数据展示'],
    ['Tabs', '数据展示'],
    ['Tag', '数据展示'],
    ['Timeline', '数据展示'],
    ['Tooltip', '数据展示'],
    ['Tour', '数据展示'],
    ['Tree', '数据展示'],
    ['Watermark', '数据展示'],
    
    // 反馈
    ['Alert', '反馈'],
    ['Drawer', '反馈'],
    ['Message', '反馈'],
    ['Modal', '反馈'],
    ['Notification', '反馈'],
    ['Popconfirm', '反馈'],
    ['Progress', '反馈'],
    ['Result', '反馈'],
    ['Skeleton', '反馈'],
    ['Spin', '反馈'],
    
    // 其他
    ['Anchor', '其他'],
    ['BackTop', '其他'],
    ['ConfigProvider', '其他'],
    ['App', '其他'],
    ['Locale', '其他'],
  ]);

  constructor() {
    super('AntDesignScraper', 'https://ant.design');
  }

  /**
   * 执行数据抓取
   */
  async scrape(): Promise<ScrapingResult> {
    const startTime = Date.now();
    const result: ScrapingResult = {
      success: false,
      count: 0,
      data: [],
      errors: [],
      timestamp: new Date(),
      duration: 0,
    };

    try {
      this.log('🚀 开始抓取 Ant Design 组件数据...');

      // 1. 获取组件列表
      this.emitProgress({
        stage: '获取组件列表',
        current: 0,
        total: 100,
        message: '正在访问组件页面...'
      });

      const componentUrls = await this.getComponentUrls();
      this.log(`📋 发现 ${componentUrls.length} 个组件`);

      // 2. 抓取每个组件的详细信息
      const components: ComponentData[] = [];
      for (let i = 0; i < componentUrls.length; i++) {
        const componentUrl = componentUrls[i];
        if (!componentUrl) continue;
        
        this.emitProgress({
          stage: '抓取组件详情',
          current: i + 1,
          total: componentUrls.length,
          item: componentUrl.name,
          message: `正在抓取 ${componentUrl.name}...`
        });

        try {
          const componentData = await this.scrapeComponent(componentUrl);
          if (componentData) {
            components.push(componentData);
            this.log(`✅ 成功抓取: ${componentData.name}`);
          }
        } catch (error) {
          const errorMsg = `抓取组件 ${componentUrl.name} 失败: ${error instanceof Error ? error.message : String(error)}`;
          result.errors.push(errorMsg);
          this.error(errorMsg);
        }

        // 遵守速率限制
        await this.delay(this.rateLimitDelay);
      }

      result.data = components;
      result.count = components.length;
      result.success = true;
      
      this.log(`🎉 抓取完成! 成功收集 ${components.length} 个组件`);

    } catch (error) {
      const errorMsg = `抓取过程发生错误: ${error instanceof Error ? error.message : String(error)}`;
      result.errors.push(errorMsg);
      this.error(errorMsg);
    }

    result.duration = Date.now() - startTime;
    return result;
  }

  /**
   * 获取所有组件的URL列表
   */
  private async getComponentUrls(): Promise<Array<{ name: string; url: string; category: string }>> {
    const html = await this.fetchPage('/components/overview');
    const $ = this.parseHtml(html);
    const componentUrls: Array<{ name: string; url: string; category: string }> = [];

    // 查找组件链接
    $('a[href*="/components/"]').each((_, element) => {
      const $link = $(element);
      const href = $link.attr('href');
      const text = this.cleanText($link.text());
      
      if (href && href.includes('/components/') && text && !href.includes('overview')) {
        // 提取组件名称
        const componentName = href.split('/components/')[1]?.split('/')[0] || '';
        if (componentName && componentName !== 'overview') {
          const normalizedName = this.normalizeComponentName(componentName);
          const category = this.categoryMap.get(normalizedName) || '其他';
          
          componentUrls.push({
            name: normalizedName,
            url: href,
            category
          });
        }
      }
    });

    // 去重并排序
    const uniqueComponents = Array.from(
      new Map(componentUrls.map(c => [c.name, c])).values()
    ).sort((a, b) => a.name.localeCompare(b.name));

    return uniqueComponents;
  }

  /**
   * 抓取单个组件的详细信息
   */
  private async scrapeComponent(componentInfo: { name: string; url: string; category: string }): Promise<ComponentData | null> {
    try {
      const html = await this.fetchPage(componentInfo.url);
      const $ = this.parseHtml(html);

      // 提取组件基本信息
      const title = this.extractTitle($) || componentInfo.name;
      const description = this.extractDescription($) || DataConverter.generateDefaultDescription(componentInfo.name, componentInfo.category);
      
      // 提取API文档
      const props = this.extractProps($);
      const examples = this.extractExamples($, componentInfo.name);
      const imports = this.generateImports(componentInfo.name);

      const componentData: ComponentData = {
        name: componentInfo.name,
        category: componentInfo.category,
        title: title,
        description: description,
        documentation_url: this.normalizeUrl(componentInfo.url),
        api_reference: this.normalizeUrl(componentInfo.url + '#api'),
        version: '5.x',
        tags: DataConverter.generateTags({
          name: componentInfo.name,
          category: componentInfo.category,
          title,
          description,
          tags: [],
          props: [],
          examples: [],
          imports: []
        }),
        props,
        examples,
        imports,
      };

      // 验证并修复数据完整性
      const validation = DataConverter.validateAndFixComponent(componentData);
      if (!validation.valid) {
        this.error(`组件 ${componentInfo.name} 数据无效: ${validation.errors.join(', ')}`);
        return null;
      }

      // 使用修复后的数据
      const fixedComponentData = validation.fixedData;
      
      // 如果描述被修复了，记录日志
      if (componentData.description !== fixedComponentData.description) {
        this.log(`🔧 组件 ${componentInfo.name} 描述已自动修复: "${fixedComponentData.description}"`);
      }

      return fixedComponentData;

    } catch (error) {
      this.error(`抓取组件 ${componentInfo.name} 失败: ${error instanceof Error ? error.message : String(error)}`);
      return null;
    }
  }

  /**
   * 提取组件标题
   */
  private extractTitle($: CheerioAPI): string {
    // 尝试多种选择器
    const selectors = [
      'h1',
      '.ant-typography h1',
      '[data-testid="page-title"]',
      '.markdown h1'
    ];

    for (const selector of selectors) {
      const title = $(selector).first().text();
      if (title) {
        const cleanTitle = this.cleanText(title);
        if (cleanTitle) {
          return cleanTitle.split(' ')[0] || ''; // 只取第一部分，去掉描述
        }
      }
    }

    return '';
  }

  /**
   * 提取组件描述
   */
  private extractDescription($: CheerioAPI): string {
    const selectors = [
      '.ant-typography p:first',
      '.markdown > p:first',
      'h1 + p',
      '.component-description'
    ];

    for (const selector of selectors) {
      const desc = $(selector).text();
      if (desc && desc.length > 10) {
        return this.cleanText(desc);
      }
    }

    return '';
  }

  /**
   * 提取组件属性
   */
  private extractProps($: CheerioAPI): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    const props: Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> = [];

    // 查找API表格
    $('table').each((_, table) => {
      const $table = $(table);
      const $headers = $table.find('thead th');
      
      // 检查是否是属性表格
      const headerTexts = $headers.map((_, th) => $(th).text().toLowerCase()).get();
      if (headerTexts.includes('属性') || headerTexts.includes('property') || headerTexts.includes('参数')) {
        
        $table.find('tbody tr').each((_, row) => {
          const $cells = $(row).find('td');
          if ($cells.length >= 3) {
            const name = this.cleanText($cells.eq(0).text());
            const description = this.cleanText($cells.eq(1).text());
            const type = this.cleanText($cells.eq(2).text());
            const defaultValue = $cells.length > 3 ? this.cleanText($cells.eq(3).text()) : undefined;

            if (name && type) {
              props.push({
                name,
                type: DataConverter.parseTypeDefinition(type),
                required: !defaultValue && !type.includes('?'),
                default_value: defaultValue !== '-' ? defaultValue : undefined,
                description: description !== '-' ? description : undefined,
              });
            }
          }
        });
      }
    });

    return props;
  }

  /**
   * 提取代码示例
   */
  private extractExamples($: CheerioAPI, componentName: string): Array<{ title: string; code: string; description?: string }> {
    const examples: Array<{ title: string; code: string; description?: string }> = [];

    // 查找代码块
    $('pre code, .ant-highlight pre').each((index, element) => {
      const $code = $(element);
      const code = $code.text();
      
      if (code && code.includes(componentName) && code.includes('import')) {
        const title = `示例 ${index + 1}`;
        const formattedCode = DataConverter.formatCode(code);
        
        if (formattedCode.length > 20) {
          examples.push({
            title,
            code: formattedCode,
            description: `${componentName} 基础用法示例`
          });
        }
      }
    });

    // 如果没有找到示例，生成基础示例
    if (examples.length === 0) {
      examples.push({
        title: '基础用法',
        code: this.generateBasicExample(componentName),
        description: `${componentName} 的基础使用示例`
      });
    }

    return examples.slice(0, 5); // 限制示例数量
  }

  /**
   * 生成组件导入信息
   */
  private generateImports(componentName: string): Array<{ import_path: string; import_name: string; is_default: boolean }> {
    return [
      {
        import_path: 'antd',
        import_name: componentName,
        is_default: false
      }
    ];
  }

  /**
   * 规范化组件名称
   */
  private normalizeComponentName(name: string): string {
    // 转换为 PascalCase
    return name
      .split('-')
      .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
      .join('');
  }

  /**
   * 生成基础示例代码
   */
  private generateBasicExample(componentName: string): string {
    const basicExamples: { [key: string]: string } = {
      'Button': `import { Button } from 'antd';

export default () => (
  <Button type="primary">
    Primary Button
  </Button>
);`,
      
      'Input': `import { Input } from 'antd';

export default () => (
  <Input placeholder="请输入内容" />
);`,
      
      'Table': `import { Table } from 'antd';

const columns = [
  {
    title: 'Name',
    dataIndex: 'name',
    key: 'name',
  },
];

const dataSource = [
  {
    key: '1',
    name: 'John Brown',
  },
];

export default () => (
  <Table dataSource={dataSource} columns={columns} />
);`,
    };

    return basicExamples[componentName] || `import { ${componentName} } from 'antd';

export default () => (
  <${componentName} />
);`;
  }
}